package com.atguigu.tingshu.album.service.impl;

import cn.hutool.core.collection.CollectionUtil;
import com.alibaba.fastjson.JSONObject;
import com.atguigu.tingshu.album.mapper.*;
import com.atguigu.tingshu.album.service.BaseCategoryService;
import com.atguigu.tingshu.common.cache.GuiGuCache;
import com.atguigu.tingshu.model.album.*;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import java.util.ArrayList;
import java.util.Collection;
import java.util.List;
import java.util.Map;
import java.util.stream.Collectors;

@Service
@SuppressWarnings({"all"})
public class BaseCategoryServiceImpl extends ServiceImpl<BaseCategory1Mapper, BaseCategory1> implements BaseCategoryService {

    @Autowired
    private BaseCategory1Mapper baseCategory1Mapper;

    @Autowired
    private BaseCategory2Mapper baseCategory2Mapper;

    @Autowired
    private BaseCategory3Mapper baseCategory3Mapper;

    @Autowired
    private BaseCategoryViewMapper baseCategoryViewMapper;


    @Autowired
    private BaseAttributeMapper baseAttributeMapper;


    /**
     * TODO 后续可以考虑放入Redis缓存
     * 查询所有1,2,3级分类列表
     *
     * @return
     */
    @Override
    public List<JSONObject> getBaseCategoryList() {
        //0.创建封装所有1级分类的集合
        List<JSONObject> jsonObjectList = new ArrayList<>();
        //1.查询分类视图获取所有记录
        List<BaseCategoryView> allCategoryList = baseCategoryViewMapper.selectList(null);
        if (CollectionUtil.isNotEmpty(allCategoryList)) {
            //2.处理1级分类数据
            //2.1 按1级分类ID进行分组 利用Stream流进行分组 Map中Key是1级分类ID  Map中Value是"1级"分类列表
            Map<Long, List<BaseCategoryView>> map1 = allCategoryList
                    .stream()
                    .collect(Collectors.groupingBy(BaseCategoryView::getCategory1Id));
            //2.2 遍历1级分类Map
            for (Map.Entry<Long, List<BaseCategoryView>> entry1 : map1.entrySet()) {
                //2.2.1 构建1级分类对象
                JSONObject jsonObject1 = new JSONObject();
                //2.2.2 封装1级分类ID
                Long category1Id = entry1.getKey();
                //2.2.2 封装1级分类名称
                String category1Name = entry1.getValue().get(0).getCategory1Name();

                //2.3 将1级分类对象放入1级分类的集合
                jsonObject1.put("categoryId", category1Id);
                jsonObject1.put("categoryName", category1Name);
                //3.处理2级分类数据
                //3.1 对"1级"分类列表，按2级分类ID进行分组 利用Stream流进行分组 Map中Key是2级分类ID  Map中Value是"2级"分类列表
                Map<Long, List<BaseCategoryView>> map2 = entry1.getValue()
                        .stream()
                        .collect(Collectors.groupingBy(BaseCategoryView::getCategory2Id));
                //3.2 创建2级分类JSON集合
                List<JSONObject> jsonObject2List = new ArrayList<>();
                for (Map.Entry<Long, List<BaseCategoryView>> entry2 : map2.entrySet()) {
                    //3.3 构建2级分类对象
                    JSONObject jsonObject2 = new JSONObject();
                    //3.3.1 封装2级分类ID
                    Long category2Id = entry2.getKey();
                    //3.3.2 封装2级分类名称
                    String category2Name = entry2.getValue().get(0).getCategory2Name();
                    //3.4 将2级分类对象放入2级分类的集合
                    jsonObject2.put("categoryId", category2Id);
                    jsonObject2.put("categoryName", category2Name);
                    //4.处理3级分类数据
                    //4.1 创建3级分类对象集合。
                    List<JSONObject> jsonObjects3List = new ArrayList<>();
                    //4.2 对"2级"分类视图列表进行遍历，封装3级分类对象
                    for (BaseCategoryView baseCategoryView : entry2.getValue()) {
                        //4.3 构建3级分类对象
                        JSONObject jsonObject3 = new JSONObject();
                        //4.3.1 封装3级分类ID
                        jsonObject3.put("categoryId", baseCategoryView.getCategory3Id());
                        //4.3.2 封装3级分类名称
                        jsonObject3.put("categoryName", baseCategoryView.getCategory3Name());
                        //4.4 将3级分类对象放入3级分类的集合
                        jsonObjects3List.add(jsonObject3);
                    }
                    //4.5 将3级分类集合放入2级分类对象中"categoryChild"属性中
                    jsonObject2.put("categoryChild", jsonObjects3List);
                    jsonObject2List.add(jsonObject2);
                    //3.5 将2级分类集合放入一级分类对象中"categoryChild"属性中
                    jsonObject1.put("categoryChild", jsonObject2List);
                }
                jsonObjectList.add(jsonObject1);
            }
        }
        return jsonObjectList;
    }

    /**
     * TODO 后续可以考虑放入Redis缓存
     * 根据1级分类ID查询标签列表（包含标签值列表）
     *
     * @param category1Id
     * @return
     */
    @Override
    public List<BaseAttribute> getAttributeByC1Id(Long category1Id) {
        //1.方式一：根据1级分类ID查询所有标签列表，遍历标签获取标签下包含标签值列表
        //2.方法二：采用调用持久层动态SQL
        return baseAttributeMapper.getAttributeByC1Id(category1Id);
    }

    /**
     * 根据3级分类ID查询分类视图对象
     *
     * @param category3Id
     * @return
     */
    @Override
    @GuiGuCache(prefix = "category:categoryview:")
    public BaseCategoryView getCategoryView(Long category3Id) {
        return baseCategoryViewMapper.selectById(category3Id);
    }

    /**
     * 根据1级分类ID查询置顶7个三级分类列表
     *
     * @param category1Id
     * @return
     */
    @Override
    public List<BaseCategory3> getTop7BaseCategory3(Long category1Id) {
        //1.根据1级分类ID查询包含2级分类ID列表
        LambdaQueryWrapper<BaseCategory2> baseCategory2LambdaQueryWrapper = new LambdaQueryWrapper<>();
        baseCategory2LambdaQueryWrapper.eq(BaseCategory2::getCategory1Id, category1Id);
        baseCategory2LambdaQueryWrapper.select(BaseCategory2::getId);
        List<BaseCategory2> baseCategory2List = baseCategory2Mapper.selectList(baseCategory2LambdaQueryWrapper);
        //2.根据2级分类ID列表查询包含3级分类列表
        if (CollectionUtil.isNotEmpty(baseCategory2List)) {
            List<Long> baseCategory2IdList = baseCategory2List.stream().map(BaseCategory2::getId).collect(Collectors.toList());
            LambdaQueryWrapper<BaseCategory3> baseCategory3LambdaQueryWrapper = new LambdaQueryWrapper<>();
            //2.1 封装查询条件 包含在二级分类ID下的三级分类
            baseCategory3LambdaQueryWrapper.in(BaseCategory3::getCategory2Id, baseCategory2IdList);
            //2.2 查询置顶分类
            baseCategory3LambdaQueryWrapper.eq(BaseCategory3::getIsTop, 1);
            //2.3 根据序号降序排
            baseCategory3LambdaQueryWrapper.orderByAsc(BaseCategory3::getOrderNum);
            //2.4 限制返回记录数：7个
            baseCategory3LambdaQueryWrapper.last("limit 7");
            return baseCategory3Mapper.selectList(baseCategory3LambdaQueryWrapper);
        }
        return null;
    }

    /**
     * TODO 后续可以考虑放入Redis缓存
     * 查询1级分类下包含二三级分类列表
     *
     * @param category1Id
     * @return
     */
    @Override
    public JSONObject getBaseCategory1List(Long category1Id) {
        //1.处理1级分类
        JSONObject jsonObject1 = new JSONObject();
        //1.1 根据1级分类ID查询分类视图得到列表
        LambdaQueryWrapper<BaseCategoryView> queryWrapper = new LambdaQueryWrapper<>();
        queryWrapper.eq(BaseCategoryView::getCategory1Id, category1Id);
        List<BaseCategoryView> baseCategoryViewList = baseCategoryViewMapper.selectList(queryWrapper);
        //1.1 封装1级分类JSON对象
        if (CollectionUtil.isNotEmpty(baseCategoryViewList)) {
            BaseCategoryView baseCategoryView = baseCategoryViewList.get(0);
            String category1Name = baseCategoryView.getCategory1Name();
            jsonObject1.put("categoryId", category1Id);
            jsonObject1.put("categoryName", category1Name);
            //2.TODO 处理2级分类
            //2.1 创建2级分类对象集合
            List<JSONObject> jsonObject2List = new ArrayList<>();
            //2.2 按2级分类ID进行分组得到Map
            Map<Long, List<BaseCategoryView>> map2 = baseCategoryViewList
                    .stream()
                    .collect(Collectors.groupingBy(BaseCategoryView::getCategory2Id));
            //2.3 遍历2级分类Map封装二级分类对象
            for (Map.Entry<Long, List<BaseCategoryView>> entry2 : map2.entrySet()) {
                Long category2Id = entry2.getKey();
                String category2Name = entry2.getValue().get(0).getCategory2Name();
                JSONObject jsonObject2 = new JSONObject();
                jsonObject2.put("categoryId", category2Id);
                jsonObject2.put("categoryName", category2Name);
                jsonObject2List.add(jsonObject2);
                //3.TODO 处理3级分类
                //3.1 创建3级分类对象集合
                List<JSONObject> jsonObject3List = new ArrayList<>();
                //3.2 遍历2级分类列表，封装三级分类对象
                for (BaseCategoryView categoryView : entry2.getValue()) {
                    JSONObject jsonObject3 = new JSONObject();
                    jsonObject3.put("categoryId", categoryView.getCategory3Id());
                    jsonObject3.put("categoryName", categoryView.getCategory3Name());
                    jsonObject3List.add(jsonObject3);
                }
                //3.3 将3级分类对象集合加入2级分类对象中"categoryChild"属性中
                jsonObject2.put("categoryChild", jsonObject3List);
            }
            //2.4 将2级分类对象放入2级分类的集合，将2级分类集合放入一级分类对象中"categoryChild"属性中
            jsonObject1.put("categoryChild", jsonObject2List);
        }
        return jsonObject1;
    }
}
